﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using CRM.Models;
using CRM.Models.Email;
using CRM.Services.Email;
using CRM.ViewModels.Email;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace CRM.Controllers.Email
{
    [Route("api/[controller]")]
    [ApiController]
    public class EmailSendFreeController : BaseController
    {
        private readonly MyDbContext _dbContext;
        private readonly UserManager<User> _userManager;
        private readonly EmailMarketingService _emailMarketingService;

        public EmailSendFreeController(MyDbContext dbContext, UserManager<User> userManager,
            EmailMarketingService emailMarketingService)
        {
            _dbContext = dbContext;
            _userManager = userManager;
            _emailMarketingService = emailMarketingService;
        }

        [HttpGet(nameof(GetInit))]
        public async Task<ResultStruct> GetInit()
        {
            var user = await _userManager.GetUserAsync(User);
            var model = _dbContext.EmailConfig.Where(m =>
                m.OemId == user.OemId && m.CompanyId == user.CompanyId && m.GroupId == user.GroupId &&
                m.UserId == user.Id);
            var tep = await model.ToListAsync();
            var groupIds = tep.Select(m => m.EmailConfigGroupId).Distinct();
            _ = await _dbContext.EmailConfigGroup
                .Where(m => m.OemId == user.OemId && m.CompanyId == user.CompanyId && m.GroupId == user.GroupId &&
                            m.UserId == user.Id)
                .Where(m => groupIds.Contains(m.Id))
                .ToListAsync();
            var temp =
                _dbContext.EmailConfigGroup.Local
                    .AsQueryable()
                    .Include(m => m.EmailConfigs)
                    .Select(m => new
                    {
                        Label = m.Name, Value = m.Id,
                        Children = m.EmailConfigs.Select(l => new { Label = l.EmailAddress, Value = l.Id })
                    })
                    .ToList();
            temp = temp.Prepend(new
            {
                Label = "暂无分组", Value = 0,
                Children = tep.Where(l => l.EmailConfigGroupId == 0)
                    .Select(l => new { Label = l.EmailAddress, Value = l.Id })
            }).ToList();

            return Success(new { listOfAuthorizedMailbox = temp });
            // return Success();
        }

        [HttpPost(nameof(Create))]
        public async Task<ResultStruct> Create(EmailMarketingVM vm)
        {
            await Task.Run(() => { });
            return Success();
            // var emailConfig = await _dbContext.EmailConfig.FindAsync(vm.Addresser);
            // try{
            //     var config = new ConfigurationRoot(new List<IConfigurationProvider>() { });
            //     var renderer = RazorRendererFactory.MakeInstance(config);
            //     var smtpMailer = new SmtpMailer(renderer, emailConfig.Host, emailConfig.Port, emailConfig.EmailAddress,
            //         emailConfig.Secret);
            //     await smtpMailer.SendAsync(vm.EmailContent, vm.EmailSubject, vm.AddresseeRecipient, emailConfig.EmailAddressRecipient, null, null,
            //         null, null);
            //     return Success();
            // }catch(Exception e)
            // {
            //     return Error(e.Message);
            // }


            // if (!ModelState.IsValid) return Error(message: ModelState.ToString());
            // var model = vm.NewModel();
            // await _dbContext.EmailSendHistory.AddAsync(model);
            // await _dbContext.SaveChangesAsync();
        }

        [HttpGet("[action]/{id:int}")]
        public async Task<ResultStruct> GetAddressees(int id)
        {
            var user = await _userManager.GetUserAsync(User);
            var emailMarketing =
                await _dbContext.EmailMarketing
                    .Where(m => m.OemId == user.OemId && m.CompanyId == user.CompanyId && m.GroupId == user.GroupId &&
                                m.UserId == user.Id).Where(m => m.Id == id).FirstOrDefaultAsync();

            if (emailMarketing is null)
                return Error(message: "任务不存在");

            if (emailMarketing.State == EmailMarketing.StateEnum.Canceled ||
                emailMarketing.State == EmailMarketing.StateEnum.Completed)
                return Error(message: "无权操作");

            if (emailMarketing.SendingNum >= emailMarketing.SubmitNum)
            {
                emailMarketing.SetState(EmailMarketing.StateEnum.Completed);
                await _dbContext.SaveChangesAsync();
                return Error(message: "无权操作");
            }

            var sendNum = await _dbContext.EmailSendHistory.Where(e => e.Source == emailMarketing.Id)
                .Select(e => e.ReceiverEmail).Distinct().CountAsync();

            var addressers = emailMarketing.AddresserObj;
            var addresserIds = addressers.Select(a => a.Id).ToArray();
            // 仅获取可发送的发件箱
            addressers = await _dbContext.EmailConfig.Where(e =>
                    addresserIds.Contains(e.Id) && (e.MaxLastDaySendNum <= 0 || e.LastDaySendNum < e.MaxLastDaySendNum))
                .ToListAsync();

            if (!addressers.Any())
            {
                await _emailMarketingService.SetState(emailMarketing.Id, EmailMarketing.StateEnum.Canceled,
                    EmailMarkeingLog.TypeEnum.Negative, "找不到可用的发件箱,请检查发件箱的每日最大发送数量限制");
                return Error(message: "找不到可用的发件箱");
            }

            // 当发件箱数量大于100, 收件箱等于100时，会导致客户端只使用前100个发件箱
            // 因此当发件箱数量大于100，使用发件箱的数量
            var addresseesCount = Math.Max(100, addressers.Count);
            var addressees = emailMarketing.AddresseeObj.Skip(sendNum).Take(addresseesCount).ToArray();

            var hasLimitAddressers = addressers.Where(a => a.MaxLastDaySendNum > 0).ToList();
            if (hasLimitAddressers.Any())
            {
                // 收件人数量为最小的发件箱可发送数量
                var senderNum = hasLimitAddressers.Min(a => a.MaxLastDaySendNum - a.LastDaySendNum);
                var canUseSenderNum = emailMarketing.FreeEmailSettingObj.SendMethod switch
                {
                    SendMethod.Random => senderNum,
                    SendMethod.Asc => Math.Min(addressees.Length, senderNum * addressers.Count),
                    _ => senderNum,
                };
                addressees = addressees.Take(canUseSenderNum).ToArray();
            }

            int[] emailTemplateIds = new int[] { };
            try
            {
                emailTemplateIds = JsonConvert.DeserializeObject<int[]>(emailMarketing.EmailTemplateIds);
            }
            catch
            {
            }

            var emailTemplates =
                await _dbContext.EmailTemplate.Where(e => emailTemplateIds.Contains(e.Id)).ToArrayAsync();

            return Success(
                new
                {
                    emailTemplates,
                    addressers,
                    addressees,
                    ReadUrls = addressees.Select(m =>
                        _emailMarketingService.BuildReadUrl(emailMarketing.Id, m.Addressee))
                });
        }

        // [HttpGet(nameof(Index))]
        // public async Task<ResultStruct> Index()
        // {
        //     return Success(await _dbContext.EmailSendFree.ToPaginateAsync());
        // }
        //
        // [HttpGet(nameof(SendingFree))]
        // public async Task<ResultStruct> SendingFree()
        // {
        //     return Success(await _dbContext.EmailSendFree.Where(m => m.SendingType == EmailSendFree.SendingTypeEnum.Free).ToPaginateAsync());
        // }        
        //
        // [HttpGet(nameof(SendingByServer))]
        // public async Task<ResultStruct> SendingByServer()
        // {
        //     return Success(await _dbContext.EmailSendFree.Where(m => m.SendingType == EmailSendFree.SendingTypeEnum.Server).ToPaginateAsync());
        // }


        // // GET
        // [HttpPost(nameof(Create))]
        // public async Task<ResultStruct> Create(EmailSendFreeCreateVM vm)
        // {
        //     if (!ModelState.IsValid) return Error(message: ModelState.ToString());
        //     var model = vm.NewModel();
        //     System.Console.WriteLine(model);
        //     await _dbContext.EmailSendFree.AddAsync(model);
        //     await _dbContext.SaveChangesAsync();
        //     return Success();
        // }

        // [HttpGet(nameof(Info))]
        // public async Task<ResultStruct> Info([FromQuery] int id)
        // {
        //     return Success(await _dbContext.EmailSendFree.FindAsync(id));
        // }
    }
}